// dubbo_method 的 inbody、outbody 的树形结构转化方法
import './MethodBody.scss';
import {Col, Row, Input, Tooltip, Select, Icon, Form, message, Switch } from 'antd';
const FormItem = Form.Item;
import React from 'react';
const {Option} = Select;

// TODO: 常量宏

exports.getIsTree = (data) => {
  if (data && data.children) {
    return true;
  } else {
    return false;
  }
}

const getDelIsAvailable = (indexArray, state, treeIndex) => {
  let ret = true;
  let dataSource = state.dataSource.concat();
  let parentValue = dataSource;
  indexArray.map((value, index) => {
    if (value === treeIndex) {
    } else if (index === indexArray.length - 1) {
    } else if (index === indexArray.length - 2 && value === 'children') {
    } else {
      parentValue = parentValue[value];
    }
  });
  if (parentValue.field_type && parentValue.field_type === 'List') {
    ret = false;
  }
  return ret;
}

const getCreateChildIsAvailable = (data) => {
  let ret = false;
  if (data && data.children && data.field_type === 'Object') {
    ret = true;
  }
  return ret;
}

const getCreateBroIsAvailable = (indexArray, state, treeIndex) => {
  let ret = false;
  let dataSource = state.dataSource.concat();
  let parentValue = dataSource;
  let ifChange = false;
  indexArray.map((value, index) => {
    if (value === treeIndex) {
    } else if (index === indexArray.length - 1) {
    } else if (index === indexArray.length - 2 && value === 'children') {
    }else {
      parentValue = parentValue[value];
      ifChange = true;
    }
  });
  if (!ifChange || (parentValue.field_type && parentValue.field_type === 'Object')) {
    ret = true;
  }
  return ret;
}

const getIsListChild = (indexArray, state, treeIndex) => {
  let ret = false;
  let dataSource = state.dataSource.concat();
  let parentValue = dataSource;
  indexArray.map((value, index) => {
    if (value === treeIndex) {
    } else if (index === indexArray.length - 1) {
    } else if (index === indexArray.length - 2 && value === 'children') {
    } else {
      parentValue = parentValue[value];
    }
  });
  if (!(parentValue.field_type == undefined ) && parentValue.field_type === 'List') {
    ret = true;
  }
  return ret;
}

// 只能处理单个值
const getIndexArray = (parentIndexArray, newIndex) => {
  let ret = parentIndexArray.concat();
  ret.push(newIndex);
  return parentIndexArray;
}
exports.getIndexArray = getIndexArray


// 只能处理单个值
const getFormIndex = (indexArray) => {
  let ret = '';
  indexArray.map((value, index) => {
    if (index === 0) {
      ret = ret + value;
    } else {
      ret = ret + '[' + value + ']';
    }
  });
  return ret;
}
exports.getFormIndex = getFormIndex

// 数值更改时获取更改的state, 只能处理单个值
const setNewState = (indexArray, formValue, state, setState, treeIndex) => {
  let ret = {dataSource: state.dataSource.concat()};
  let targetValue = ret.dataSource;
  let isChangeExpand = false;
  let expandedKeys = state.expandedKeys.concat();
  indexArray.map((value, index) => {
    if (index === indexArray.length - 1) {
      // 当field_type更改时,处理children
      if (value === 'field_type') {
        if (formValue === 'Object' ) {
          targetValue['children'] = [
            {
              name: 'field_1',
              field_type: 'String'
            }
          ];
          isChangeExpand = true
          let tempIndexArray = indexArray.concat()
          delete tempIndexArray[tempIndexArray.length - 1]
          expandedKeys = expandedKeys.concat(getFormIndex(tempIndexArray))
        } else if(formValue === 'List') {
          targetValue['children'] = [
            {
              name: 'String',
              field_type: 'String'
            }
          ];
          isChangeExpand = true
          let tempIndexArray = indexArray.concat()
          delete tempIndexArray[tempIndexArray.length - 1]
          expandedKeys = expandedKeys.concat(getFormIndex(tempIndexArray))
        } else {
          delete targetValue['children'];
        }
      }
      targetValue[value] = formValue;
    } else if(value === treeIndex) {
    } else {
      targetValue = targetValue[value];
    }
  });
  if (isChangeExpand) {
    setState({
      dataSource: ret.dataSource,
      expandedKeys: expandedKeys
    })
  } else {
    setState({dataSource: ret.dataSource})
  }
  return ret;
}
exports.setNewState = setNewState

const onSelectChange = (value, indexArray, state, setState, treeIndex) => {
  setNewState(indexArray, value, state, setState, treeIndex);
}
exports.onSelectchange = onSelectChange

const onRequiredChange = (checked, indexArray, state, setState, treeIndex) => {
  setNewState(indexArray, checked, state, setState, treeIndex)
}

// 添加兄弟节点
const onAddBrother = (indexArray, state, setState, treeIndex) => {
  if (indexArray.length <= 0) {
    return;
  }
  let cloneDataSource = state.dataSource.concat();
  let targetValue = cloneDataSource;
  indexArray.map((value, index) => {
    if (index === indexArray.length - 1) {
      let node = {
        name: 'field_' + (targetValue.length + 1),
        field_type: 'String'
      };
      targetValue.push(node);
    } else if(value === treeIndex) {
    } else {
      targetValue = targetValue[value];
    }
  });
  setState({dataSource: cloneDataSource});
}
exports.onAddBrother = onAddBrother

// 添加子节点,返回新的indexArray
const onAddChild = (indexArray, state, setState, treeIndex) => {
  let ret = [];
  let cloneDataSource = state.dataSource.concat();
  let targetValue = cloneDataSource;
  indexArray.map((value, index) => {
    if (value === treeIndex) {
    }else{
      ret[index] = value;
      targetValue = targetValue[value];
    }
  });
  ret.push('children');
  ret.push(0);
  targetValue = targetValue['children'];
  let node = {
    name: 'field_' + (targetValue.length + 1),
    field_type: 'String'
  }
  targetValue.push(node);
  setState({
      expandedKeys: state.expandedKeys.concat().concat(getFormIndex(indexArray)),
      dataSource: cloneDataSource
    });
  return ret;
}
exports.onAddChild = onAddChild

// 删除节点
const onDel = (indexArray, state, setState, treeIndex) => {
  let cloneDataSource = state.dataSource.concat();
  let targetValue = cloneDataSource;
  let cloneExpandedKeys = state.expandedKeys.concat();
  indexArray.map((value, index) => {
    if (index === indexArray.length - 1) {
      delete targetValue[value];
      let formIndex = getFormIndex(indexArray)
      let indexInExpand = cloneExpandedKeys.indexOf(formIndex)
      if (indexInExpand >= 0) {
        delete cloneExpandedKeys[indexInExpand]
      }
    } else if(value === treeIndex) {
    } else {
      targetValue = targetValue[value];
    }
  });
  setState({
    dataSource: cloneDataSource,
    expandedKeys: cloneExpandedKeys
  });
}
exports.onDel = onDel

// 转化为json string
const bodyToJson = (dataSource, spaceNum) => {
  if (typeof(dataSource) === 'string') {
    return dataSource;
  }
  if (spaceNum == undefined) {
    return JSON.stringify(dataSource);
  } else {
    return JSON.stringify(dataSource, null, spaceNum);
  }
}
exports.bodyToJson = bodyToJson

// json to body
const jsonToBody = (str) => {
  if (typeof(str) === 'object') {
    return str;
  }
  const reviver = (index, value) => {
    // 去除undefined 和 null
    if (value == undefined){
      return undefined;
    }
    return value;
  }
  return JSON.parse(str, reviver);
}
exports.jsonToBody = jsonToBody

// 转化database存储的json为run运行需要的json
// @param userRandom: 是否生成随机数据, defaultValue = false
// @param useDefault: 仅在useRamdom = false 下生效, 是否使用default值, defaultValue = true
// @param listLength: list长度, 为false时代表使用随机长度 defaultVaue = 2
// @param listUseDefault: 仅在useDefault = true 下生效, list对象是否使用default值, defaultValue = true
// @param objectUseDefault: 仅在useDefault = true 下生效, object对象是否使用default值, defaultValue = true
const getRunJson = (str, useRandom, useDefault, listLength, listUseDefault, objectUseDefault) => {
  listLength = listLength == undefined ? 2 : listLength
  useRandom = useRandom == undefined ? false : true
  useDefault = useDefault == undefined ? true : false
  listUseDefault = listUseDefault == undefined ? true : false
  objectUseDefault = objectUseDefault == undefined ? true : false
  
  if (str == undefined) {
    return;
  }
  if (!(typeof(str) === 'string')) {
    return;
  }
  let ret = '';
  const getRandomLength = (minLength, maxLength) => {
    minLength = minLength == undefined ? 1 : minLength
    maxLength = maxLength == undefined ? minLength + 9 : maxLength
    return parseInt(Math.random() * (maxLength - minLength + 1) + minLength, 10)
  }
  // 获取随机数据
  const getRandomData = (type, length) => {
    const getRandomStr = (length) => {
      function randomWord(randomFlag, min, max) {
        let str = "",
          range = min,
          arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
            'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
            'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
      
        if (randomFlag) {
          range = Math.round(Math.random() * (max - min)) + min;// 任意长度
        }
        for (let i = 0; i < range; i++) {
          let pos = Math.round(Math.random() * (arr.length - 1));
          str += arr[pos];
        }
        return str;
      }
      let ret
      length = length == undefined ? getRandomLength(15, 30) : length
      ret = '' + randomWord(false, length, length)
      return ret
    }
    // 这里规定为有符号整型 十进制, length为十进制长度, length不包括符号
    // length会自动转化成绝对值
    const getRandomInt = (length) => {
      let ret
      length = length == undefined ? getRandomLength() : length
      length = Math.abs(length)
      let max = 10 * length
      ret = Math.floor(Math.random() * (max + 1))
      if(Math.round(Math.random())) {
        ret = -ret
      }
      return ret
    }
    // 当前length为小数长度, 会取绝对值
    const getRandomBigDecimal = (length) => {
      let ret
      let max = 9999999 // 整数最大值
      length = length == undefined ? 10 : length
      length = parseInt(Math.abs(length))
      ret = Math.random()
      ret = ret.toFixed(length) + Math.floor(Math.random() * (max + 1))
      if(Math.round(Math.random())) {
        ret = -ret
      }
      return ret
    }
    const mapper = {
      'String': getRandomStr,
      'Integer': getRandomInt,
      'BigDecimal': getRandomBigDecimal
    }
    ret = mapper[type](length)
    return ret;
  }

  // body 必须是一个object类型
  const process = (body) => {
    const field_type = body.field_type
    if(field_type === 'String' || field_type === 'Integer' || field_type === 'BigDecimal') {

      return useRandom ? getRandomData(field_type, body.length) : (
        useDefault ? (body.default == undefined ? null : body.default) : null
      );
    } else if(field_type === 'List') {
      if (useDefault && listUseDefault) {
        if (body.default == undefined) {
        } else {
          return body.default
        }
      }
      // 无论用户定义什么自定义类型，它肯定是一个object
      let temp_length = body.children[0].length == undefined ? 
        (listLength === false ? getRandomLength() : listLength) : body.children[0].length
      let temp_body = []
      for(var i = 0; i < temp_length; i++) {
        temp_body.push(process(body.children[0]))
      }
      return temp_body;
    } else if (field_type === 'Object') {
      if (useDefault && objectUseDefault) {
        if (body.default == undefined) {
        } else {
          return body.default
        }
      }
      let temp_body = {}
      body.children.map((value) => {
        temp_body[value.name] = process(value)
      })
      return temp_body
    }
  }
  // 获取含有随机数据的object或array
  // body必须是一个数组
  const getBodyWithRandom = (body) => {
    let ret = {}
    body.map((value) => {
      ret[value.name] = process(value)
    })
    return ret
  }
  ret = jsonToBody(str)
  ret = getBodyWithRandom(ret)
  ret = JSON.stringify(ret, 2)
  return ret;
}
exports.getRunJson = getRunJson;



const delEmpty = (dataSource) => {
  let ret = [];
  dataSource.map((value) => {
    ret = ret.concat(value);
  })
  return ret;
}
exports.delEmpty = delEmpty

// jctest
// TODO 删除str前多少个字符为某个值的expendedKeys

// json数据验证
// return: {available, message, type}
//      type: [1:全局json, 2: 单个字段json]
const checkImportJson = (json) => {
  // 验证字段
  const checkObjectField = (value) => {
    let available = true
    let message = ''

    if (!(typeof(value) === 'object')) {
      message = '数据类型错误'
      available = false
    } else if (value.name == undefined) {
      message = '字段名不能为空'
      available = false
    } else if (value.field_type == undefined) {
      message = '字段类型不能为空'
      available = false
    } else {
      switch (value.field_type) {
        case 'List': {
          if (value.children == undefined || !Array.isArray(value.children) || !(value.children.length === 1)) {
            message = 'List 的子节点有且只能有一个'
            available = false
          }
          break;
        }
        case 'Object': {
          if (value.children == undefined || !Array.isArray(value.children)) {
            message = 'Object 的children属性值应当是一个数组'
            available = false
          }
          break;
        }
        case 'String': {
          if(!(value.children == undefined)) {
            message = value.field_type + ' 不应存在children属性'
            available = false
          }
          break;
        }
        case 'BigDecimal': {
          if(!(value.children == undefined)) {
            message = value.field_type + ' 不应存在children属性'
            available = false
          }
          break;
        }
        case 'Integer': {
          if(!(value.children == undefined)) {
            message = value.field_type + ' 不应存在children属性'
            available = false
          }
          break;
        }
        default: {
          message = '不支持' + value.field_type + '类型'
          available = false
          break;
        }
      }
    }
    return {
      available: available,
      message: message
    }
  }
  // 接收array
  const checkBodyKeys = (body) => {
    let ret = {
      available: true,
      message: ''
    }
    if (!(typeof(body) === 'object')) {
      return {
        available: false,
        message: 'json所表达数据应为Object类型'
      }
    }
    if (Array.isArray(body)) {
      for (var value of body) {
        ret = checkBodyKeys(value)
        if(!ret.available) {
          break;
        } else if(!(value.children == undefined)){
          ret = checkBodyKeys(value.children)
          if (!ret.available) {
            break;
          }
        }
      }
    } else {
      ret = checkObjectField(body)
      if(!ret.available) {
      } else if (!(body.children == undefined)) {
        ret = checkBodyKeys(body.children)
      }
    }
    return ret
  }
  let ret = {
    available: false,
    message: '',
    type: 1
  }
  try {
    let tempImportBody = jsonToBody(json)
    if (Array.isArray(tempImportBody)) {
      ret.type = 1
    } else if (typeof(tempImportBody) === 'object') {
      ret.type = 2
    }
    let temp = checkBodyKeys(tempImportBody)
    ret.available = temp.available
    ret.message = temp.message
  } catch (e) {
    return {
      available: false, message: e.message, type: 0}
  }
  return ret
}
exports.checkImportJson = checkImportJson

// modal onOk
const onOk = (indexArray, state, setState, treeIndex) => {
  let tempModalData = state.modalData
  if (!checkImportJson(tempModalData)) {
    return message.error("json数据格式错误")
  }
  let cloneDataSource = state.dataSource.concat();
  let targetValue = cloneDataSource;
  indexArray.map((value, index) => {
    if (index === indexArray.length - 1) {
      targetValue[value] = jsonToBody(tempModalData)
      // TODO 删除str前多少个字符为某个值的expendedKeys
    } else if(value === treeIndex) {
    } else {
      targetValue = targetValue[value];
    }
  });
  setState({
    dataSource: cloneDataSource
  });
}
exports.onOk = onOk

// modal onCancel
// const onCancel = (setState) => {
//   setState({isShowModal: false})
// }

// @param isSaveLast: 当碰到相同名称的参数, 是否只保留最后一个, defaultValue = true
const processFormValues = (body, parentValue, isSaveFirst) => {
  isSaveFirst = isSaveFirst == undefined ? true : isSaveFirst
  let ret = [];
  let nameList = [];
  if (body == undefined || body.length === 0) {
    return ret;
  }
  let tempRet = body.concat();
  tempRet.map((value, index) => {
    if (value == undefined) {
    } else {
      if (!(parentValue == undefined) && parentValue.field_type === 'List') {
        value.name = value.field_type === 'Object' ? 
          (value.name == undefined || value.name == '' ? value.field_type : value.name) 
          : value.field_type
      }
      if (value.name == undefined) {
        tempRet[index] = undefined
      } else {
        if (value.field_type === 'Object') {
          value.children = value.children == undefined ? [] : value.children
        } else if (value.field_type === 'List') {
          if (value.children == undefined) {
            value.children = []
            value.children.push({
              name: 'String',
              field_type: 'String'
            })
          }
        } else {
          if (value.children == undefined) {
          } else {
            value.children = undefined
          }
        }
        if (!(value.children == undefined) && value.children.length > 0) {
          value.children = processFormValues(value.children, value, isSaveFirst)
        }
      }
    }
    if (!(tempRet[index] == undefined)) {
      if (isSaveFirst && nameList.includes(tempRet[index].name)) {
      } else {
        ret = ret.concat(tempRet[index])
        nameList = nameList.concat(tempRet[index].name)
      }
    } 
  })
  return ret; 
}
exports.processFormValues = processFormValues

exports.getCellComponent = (data, indexArray, form, state, setState, treeIndex) => {
  // 去除 undefined 和 null
  if (indexArray == undefined) {
    return (
      <Row key = 'error'>ERROR</Row>
    );
  } else if(indexArray.length === 0) {
    return;
  }
  const index = getFormIndex(indexArray);
  const {getFieldDecorator} = form;

  // 设置按钮回调
  const onSetting = (data, indexArray, setState) => {
    setState({
      editModalData: {
        isShow: true,
        indexArray: indexArray,
        data: bodyToJson(data, 2)
      }
    })
  }
  
  return (
    <Row key={index}>
      <Col>{state.forceUpdateView}</Col>
      {!getIsListChild(indexArray, state, treeIndex) ? (
        <Col span="4" draggable="false" className="interface-edit-item-content-col">
          <FormItem>
            {getFieldDecorator(index + '.name', {
              initialValue: data.name,
              rules: [
                {
                  required: true,
                  message: '字段名不能为空'
                }
              ]
            })(<Input placeholder="字段名" />)}
          </FormItem>
        </Col>
      ) : (
        <Col span="9" draggable="false" className="interface-edit-item-content-col">
          <FormItem>
            {getFieldDecorator(index + '.name', {
              initialValue: (data.name == undefined) ? data.field_type : data.name
            })(<Input placeholder="自定义类型, 选择Object时生效, 不输入则为选定类型" disabled={!(data.field_type == 'Object')}/>)}
          </FormItem>
        </Col>
      )}
      {!getIsListChild(indexArray, state, treeIndex) ? (
        <Col span="1" draggable="false" className="interface-edit-item-content-col">
          <FormItem>
            <Tooltip placement="topLeft" title="是否必需" arrowPointAtCenter>
              {getFieldDecorator(index + '.required', {
                valuePropName: 'checked',
                initialValue: data.required
              })(
                <Switch 
                  size="small"
                  checkedChildren={<Icon type="check" />}
                  unCheckedChildren={<Icon type="close" />}
                  onChange={(checked) => onRequiredChange(checked, indexArray.concat('required'), state, setState, treeIndex)}>
                </Switch>
              )}
            </Tooltip>
          </FormItem>
        </Col>
      ) : null}
      {!getIsListChild(indexArray, state, treeIndex) ? (
        <Col span="4" draggable="false" className="interface-edit-item-content-col">
          <FormItem>
            {getFieldDecorator(index + '.name_cn', {
              initialValue: data.name_cn
            })(<Input placeholder="字段名称" />)}
          </FormItem>
        </Col>
      ) : null}
      <Col span="2" className="interface-edit-item-content-col">
        <FormItem>

          {getFieldDecorator(index + '.field_type', {
            initialValue: data.field_type,
            rules: [
              {
                required: true,
                message: '类型不能为空'
              }
            ]
          })(
            <Select
              onChange = {(value) => onSelectChange(value, indexArray.concat('field_type'), state, setState, treeIndex)}
            >
              <Option value="String">String</Option>
              <Option value="BigDecimal">BigDecimal</Option>
              <Option value="Integer">Integer</Option>
              <Option value="List">List</Option>
              <Option value="Object">Object</Option>
            </Select>
          )}
        </FormItem>
      </Col>
      <Col span="3" draggable="false" className="interface-edit-item-content-col">
        <FormItem>
          {getFieldDecorator(index + '.length', {
            initialValue: data.length,
            rules: [
              {
                pattern: new RegExp(/^[0-9]\d*$/, "g"),
                message: "长度必须为数字"
              }
            ]
          })(<Input placeholder="长度" />)}

        </FormItem>
      </Col>
      <Col span="4" draggable="false" className="interface-edit-item-content-col">
        <FormItem>
          {getFieldDecorator(index + '.default', {
            initialValue: data.default
          })(<Input placeholder="默认值" />)}

        </FormItem>
      </Col>
      <Col span="4" draggable="false" className="interface-edit-item-content-col">
        <FormItem>
          {getFieldDecorator(index + '.desc', {
            initialValue: data.desc
          })(<Input placeholder="备注" />)}

        </FormItem>
      </Col>
      {/* TODO: 添加显示条件 */}
      <Col span="2">
        <Col span="6" className="interface-edit-item-content-col">
          <Tooltip placement="topLeft" title="设置" arrowPointAtCenter>
            <Icon
              type="setting"
              theme="twoTone"
              className="interface-edit-del-icon"
              display = 'none'
              onClick={() => onSetting(data, indexArray, setState)}
            />
          </Tooltip>
        </Col>
        <Col span="6" className="interface-edit-item-content-col">
          {
            getDelIsAvailable(indexArray, state, treeIndex) ? (
              <Tooltip placement="topLeft" title="删除" arrowPointAtCenter>
                <Icon
                  type="delete"
                  theme="twoTone"
                  className="interface-edit-del-icon"
                  display = 'none'
                  onClick={() => onDel(indexArray, state, setState, treeIndex)}
                />
              </Tooltip>
            ) : ''
          }
        </Col>
        {/* TODO: 添加显示条件 */}
        <Col span="6" className="interface-edit-item-content-col">
          {
            getCreateBroIsAvailable(indexArray, state, treeIndex) ? (
              <Tooltip placement="topLeft" title="添加兄弟节点" arrowPointAtCenter>
                <Icon
                  type="plus"
                  theme="twoTone"
                  className="interface-edit-del-icon"
                  onClick={() => onAddBrother(indexArray, state, setState, treeIndex)}
                />
              </Tooltip>
            ) : ''
          }
        </Col>
        {/* TODO: 添加显示条件 */}
        <Col span="6" className="interface-edit-item-content-col">
          {
            getCreateChildIsAvailable(data) ? (
              <Tooltip placement="topLeft" title="添加子节点" arrowPointAtCenter>
                <Icon
                  type="plus-circle"
                  theme="twoTone"
                  className="interface-edit-del-icon"
                  onClick={() => onAddChild(indexArray, state, setState, treeIndex)}
                />
              </Tooltip>
            ) : ''
          }
        </Col>
      </Col>
    </Row>
  );
}